%{
#include <stdio.h>
#include <stdlib.h>
#include "ast.h"

void yyerror(const char *s);
extern int yylex();

/* data structure  of syntax table and else   */
%}

%union {
    int num;
    double fnum;
    char *str;
    struct ASTNode *node;
}

%token <num> NUMBER
%token <fnum> FLOAT
%token <str> IDENTIFIER
%token IF ELSE DEF RETURN PRINT
%token ASSIGN EQ PLUS MINUS TIMES DIVIDE
%token COLON LPAREN RPAREN LBRACKET RBRACKET COMMA NEWLINE

%type <node> program stmt_list stmt expr

%%

program:    /* Blank */
          | program stmt_list
          ;

stmt_list:  stmt
          | stmt_list NEWLINE stmt
          ;

stmt:       expr
          | PRINT expr { $$ = create_print_node($2); }
          | DEF IDENTIFIER LPAREN RPAREN COLON NEWLINE stmt_list
            { $$ = create_function_node($2, $7); }
          | IF expr COLON NEWLINE stmt_list ELSE COLON NEWLINE stmt_list
            { $$ = create_if_else_node($2, $5, $9); }
          ;

expr:       NUMBER          { $$ = create_num_node($1); }
          | FLOAT          { $$ = create_float_node($1); }
          | IDENTIFIER     { $$ = create_var_node($1); }
          | expr PLUS expr  { $$ = create_op_node('+', $1, $3); }
          | expr EQ expr    { $$ = create_op_node('=', $1, $3); }
          ;

%%

void yyerror(const char *s) {
    fprintf(stderr, "syntax error: %s\n", s);
}

int main() {
    yyparse();
    return 0;
}